// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: taekwon

#include "coin2/exchange/base/log/order_logger.h"

#include <google/protobuf/util/message_differencer.h>
#include <gtest/gtest.h>

TEST(OrderLogger, OrderLogReader) {
  using coin2::exchange::base::order_util::OrderLogger;
  using coin2::exchange::base::order_util::OrderLogReader;

  coin::proto::AccountRequestProto req_proto;
  req_proto.set_owner("jang");
  req_proto.set_market_type("Futures");
  req_proto.set_exchange("Huobi");
  OrderLogger op_lp(req_proto, "/tmp/log_test", "test_machine");

  op_lp.InitializeWriter(1576056261418000000LL);
  EXPECT_EQ(op_lp.log_timestamp(), 1576056261418000000LL);
  EXPECT_EQ(op_lp.expiry_timestamp(), 1576056'600'000'000'000LL);

  int64_t b_timestamp = 1576056261418000000LL;
  auto ensured_path = op_lp.GetEnsuredLogPath(1577066861418000000LL);
  EXPECT_EQ(
      ensured_path,
      "/tmp/log_test/test_machine/20191211/jang.Futures.Huobi.20191223-020741.1577066861418000000");

  EXPECT_TRUE(op_lp.WriteAccountRequest(true, b_timestamp + 1000000));

  coin::proto::AccountPosition acc_pos;
  acc_pos.set_exchange("Huobi");
  acc_pos.set_market_type("Futures");
  auto pos = acc_pos.add_each_position();
  pos->set_symbol("BTC");
  pos->set_long_position(1.0);
  pos->set_short_position(-3.0);
  pos->set_net_position(-2.0);
  EXPECT_TRUE(op_lp.WritePosition(acc_pos, true, b_timestamp + 2000000));

  coin::proto::AccountBalance acc_bal;
  acc_bal.set_exchange("Huobi");
  acc_bal.set_market_type("Futures");
  auto bal = acc_bal.add_each_balance();
  bal->set_currency("BTC");
  bal->set_currency_native("BTCC");
  bal->set_total(5.0);
  bal->set_available(2.0);
  bal->set_hold(3.0);
  EXPECT_TRUE(op_lp.WriteBalance(acc_bal, true, b_timestamp + 3000000));

  // Write log on next day
  EXPECT_TRUE(op_lp.WriteAccountRequest(true, b_timestamp + 86400'000'000'000LL));

  // READ TEST
  const size_t BUF_SIZE = 100 * 1024;
  OrderLogReader proto_reader(
      req_proto,
      "/tmp/log_test",
      "test_machine",
      1576056261418000000LL,
      1576142661419000000LL,
      BUF_SIZE);
  coin::proto::OrderGatewayLog op_log_proto;

  EXPECT_TRUE(proto_reader.Read(&op_log_proto));
  EXPECT_EQ(op_log_proto.type(), coin::proto::OrderGatewayLog::ACCOUNT_REQUEST);
  EXPECT_TRUE(google::protobuf::util::MessageDifferencer::ApproximatelyEquals(
      op_log_proto.account_request(),
      req_proto));

  EXPECT_TRUE(proto_reader.Read(&op_log_proto));
  EXPECT_EQ(op_log_proto.type(), coin::proto::OrderGatewayLog::POSITION);
  EXPECT_TRUE(google::protobuf::util::MessageDifferencer::ApproximatelyEquals(
      op_log_proto.position(),
      acc_pos));

  EXPECT_TRUE(proto_reader.Read(&op_log_proto));
  EXPECT_EQ(op_log_proto.type(), coin::proto::OrderGatewayLog::BALANCE);
  EXPECT_TRUE(google::protobuf::util::MessageDifferencer::ApproximatelyEquals(
      op_log_proto.balance(),
      acc_bal));

  EXPECT_TRUE(proto_reader.Read(&op_log_proto));
  EXPECT_EQ(op_log_proto.type(), coin::proto::OrderGatewayLog::ACCOUNT_REQUEST);

  EXPECT_FALSE(proto_reader.Read(&op_log_proto));
}
